<template>
  <el-upload class="avatar-uploader" accept=".png,.jpg,.jpeg" :show-file-list="false" :http-request="onHttpRequest">
    <div v-if="modelValue" class="avatar">
      <img :src="modelValue" alt="" />
      <div class="handle">
        <el-icon class="icon-delete" @click.stop="handleDelete">
          <Delete />
        </el-icon>
      </div>
    </div>

    <el-icon v-else class="avatar-uploader-icon">
      <Plus />
    </el-icon>
  </el-upload>
</template>

<script>
import request from "@/utils/request";
import { ElMessage } from "element-plus";

export default {
  name: "avatar-uploader",

  props: {
    modelValue: {
      type: String,
      required: true,
    },

    // 文件大小限制，2M
    //  M => KB => b
    limit: {
      type: Number,
      default() {
        return 2 * 1024 * 1024;
      },
    },

    // 文件类型限制
    accept: {
      type: Array,
      default() {
        return ["image/jpeg", "image/jpg", "image/png"];
      },
    },
  },

  emits: ["update:modelValue"],

  methods: {
    /**
     * 覆盖默认的xhr行为
     * @param {Object} options 请求相关的配置项
     */
    onHttpRequest(options) {
      console.log(options);

      const { size, type } = options.file;
      if (!this.fileCheck(size, type)) {
        ElMessage.error("文件类型或大小不符合要求");
        return;
      }

      request
        .post(
          "/app/base/comm/upload",
          {
            file: options.file,
          },
          {
            headers: {
              "Content-Type": "multipart/form-data",
            },
          }
        )
        .then((data) => {
          this.$emit("update:modelValue", data);
        });
    },

    /**
     *
     * @param {*} size 文件大小
     * @param {*} type 文件类型
     * @returns true - 校验通过， false - 校验失败
     */
    fileCheck(size, type) {
      if (size > this.limit || !this.accept.includes(type)) {
        return false;
      } else {
        return true;
      }
    },

    handleDelete() {
      this.$emit("update:modelValue", "");
    },
  },
};
</script>

<style lang="scss" scoped>
.avatar-uploader {
  .avatar {
    position: relative;
    width: 120px;
    height: 120px;
    display: block;

    img {
      display: block;
      width: 100%;
      height: 100%;
    }

    .handle {
      position: absolute;
      top: 0;
      left: 0;
      display: none;
      align-items: center;
      justify-content: center;
      width: 100%;
      height: 100%;
      background-color: rgba(0, 0, 0, 0.5);
      cursor: default;
    }

    .icon-delete {
      font-size: 28px;
      color: #fff;
      cursor: pointer;
    }

    &:hover {
      .handle {
        display: flex;
      }
    }
  }
}

.avatar-uploader ::v-deep(.el-upload) {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}

.avatar-uploader ::v-deep(.el-upload:hover) {
  border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 120px;
  height: 120px;
  text-align: center;
}
</style>
